module Packets {
	import Event = Laya.Event;
	import Socket = Laya.Socket;
	import Byte = Laya.Byte;
	
	import EventDispatcher = laya.events.EventDispatcher;
	
	export class SocketClient extends EventDispatcher {

        private static _inst = null;
        private static addr:string = "ws://127.0.0.1:1234";

        private Api = {
            "TO_MSG_HEADR": 101,
            "ON_MSG_LOGIN": 102
        }
        private PacketId = {};

		private socket: Socket;
		private output: Byte;

		constructor() {
			super();
			if (SocketClient._inst !== null) {
                throw new Error("SocketClient Is An Instance Class");
            }
		}

        public static getInstance(): SocketClient {
            if (SocketClient._inst === null) {
                SocketClient._inst = new SocketClient();
                SocketClient._inst.init();
            }
            return SocketClient._inst;
        }

        public init(): void {
            for (let k in this.Api) {
                if (this.Api.hasOwnProperty(k) && typeof this.Api[k] == "number") {
                    this.PacketId[this.Api[k]] = k.replace(/^TO_|^ON_/, "").toLowerCase().replace(/_(\S)/g, (all, letter)=> {
                        return letter.toUpperCase();
                    });
                }
            }
            this.connect();
        }

		private connect(): void {
			this.socket = new Socket();
			this.socket.connectByUrl(SocketClient.addr);

			this.output = this.socket.output;

			this.socket.on(Event.OPEN, this, this.onSocketOpen);
			this.socket.on(Event.CLOSE, this, this.onSocketClose);
			this.socket.on(Event.MESSAGE, this, this.onMessageReveived);
			this.socket.on(Event.ERROR, this, this.onConnectError);
		}

		private onSocketOpen(): void {
			console.log("Connected");
		}

		private onSocketClose(): void {
			console.log("Socket closed");
		}

		private onConnectError(e: Event): void {
			console.log("error");
		}

        private onMessageReveived(message: any): void {
			console.log("Message from server: ");

            // let buffer;
			// if (typeof message == "string") {
			// 	buffer = new Uint8Array(message);
			// } else if (message instanceof ArrayBuffer) {
			// 	buffer = new Byte(message).readUTFBytes();
			// }
			
            let msg = ProtocolBuffer.getInstance().decodeData(message);
            console.log(msg);

            this.socket.input.clear();
            
            return msg;
		}

        public sendPacket(packetId: number, message: any) :void {
            // // 发送字符串
			// this.socket.send("demonstrate <sendString>");

			// // 使用output.writeByte发送
			// var message: string = "demonstrate <output.writeByte>";
			// for (var i: number = 0; i < message.length; ++i) {
			// 	this.output.writeByte(message.charCodeAt(i));
			// }
            
            let msg = {"packetId":packetId, "timestamp": new Date().valueOf()};
            msg[this.PacketId[packetId]] = message || {};

            let buffer = ProtocolBuffer.getInstance().encodeData(msg);

            this.socket.send(buffer);
            this.socket.flush();
        }
	}
}